package cn.centec.core.util;

import cn.centec.core.config.Centec6Properties;
import cn.centec.core.entity.Result;
import cn.centec.core.entity.StandardRequestParam;
import cn.centec.core.exception.WarnRuntimeException;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
 * 采购中心AIP工具
 *
 * @author 延晓磊
 * @since 2022年09月15日
 */
@Component
public class Centec6ApiUtil {

    @Resource
    private Centec6Properties centec6Properties;

    private static final Logger LOG = LoggerFactory.getLogger(Centec6ApiUtil.class);

    /**
     * 发起请求
     *
     * @param module    请求模块
     * @param method    请求方法
     * @param param     请求参数（JSON串）
     *
     * @return 请求结果
     *
     * @author 延晓磊
     * @since 2022年09月15日
     */
    public Result request(String module, String method, String param){
        // 参数签名
        String sign = DigestUtils.md5Hex(centec6Properties.getSid() + module + method + param + centec6Properties.getSecret());
        // 发起请求
        LOG.info("请求采购中心：module = {}, method = {}", module, method);
        LOG.debug("发起请求：module = {}, method = {}, param = {}, sign = {}", module, method, param, sign);
        try {
            Map<String, String> params = new HashMap<>();
            params.put("sid", centec6Properties.getSid());
            params.put("module", module);
            params.put("method", method);
            params.put("param", param);
            params.put("sign", sign);
            String result = HttpUtil.doPost(centec6Properties.getUrl(), params);
            LOG.debug("接收响应：module = {}, method = {}, param = {}, result = {}", module, method, param, result);
            return JsonUtil.parse(result, Result.class).rest();
        }catch (WarnRuntimeException e){
            LOG.warn("请求采购中心错误：module = {}, method = {}, param = {}, sign = {}, error = {}", module, method, param, sign, e.getMessage(), e);
            throw e;
        }catch (RuntimeException e){
            LOG.error("请求采购中心失败：module = {}, method = {}, param = {}, sign = {}, error = {}", module, method, param, sign, e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 接收请求
     *
     * @param param     请求参数
     * @param handler   请求处理器
     *
     * @return 响应结果
     *
     * @author 延晓磊
     * @since 2022年09月15日
     */
    @Transactional
    public Result receive(StandardRequestParam param, Supplier<Result> handler){
        // 接收请求
        LOG.info("接收采购中心：module = {}, method = {}", param.getModule(), param.getMethod());
        LOG.debug("接收请求：module = {}, method = {}, param = {}, sign = {}", param.getModule(), param.getMethod(), param.getParam(), param.getSign());
        // 验证签名
        if (!param.getSign().equals(DigestUtils.md5Hex(centec6Properties.getSid() + param.getModule() + param.getMethod() + param.getParam() + centec6Properties.getSecret()))) {
            LOG.warn("接收采购中心错误：module = {}, method = {}, param = {}, sign = {}, error = {}", param.getModule(), param.getMethod(), param.getParam(), param.getSign(), "参数签名校验错误");
            return Result.error("参数签名错误");
        }
        // 处理请求
        try {
            Result result = handler.get();
            LOG.debug("发送响应：module = {}, method = {}, param = {}, result = {}",  param.getModule(), param.getMethod(), param.getParam(), result);
            return result;
        }catch (WarnRuntimeException e){
            LOG.warn("接收采购中心错误：module = {}, method = {}, param = {}, sign = {}, error = {}", param.getModule(), param.getMethod(), param.getParam(), param.getSign(), e.getMessage(), e);
            throw e;
        }catch (RuntimeException e){
            LOG.error("接收采购中心失败：module = {}, method = {}, param = {}, sign = {}, error = {}", param.getModule(), param.getMethod(), param.getParam(), param.getSign(), e.getMessage(), e);
            throw e;
        }
    }

}
